<?php namespace nimo\common\csv;

use SplFileObject;
use DB;
use nimo\common\io\FilteredFile;

class Importer {

    private $filename;
    private $interceptor = null;
    private $configs = array();

    public function __construct($filename, $configs = array(), ImportInterceptor $interceptor) 
    {
        $this->filename = $filename;
        $this->interceptor = $interceptor;
        // 区切り文字
        $this->configs['delimiter']   = isset($configs['delimiter']) ? $configs['delimiter'] : ',';
        // 囲み文字
        $this->configs['enclosure']   = isset($configs['enclosure']) ? $configs['enclosure'] : '"';
        // エスケープ文字
        $this->configs['escape']      = isset($configs['escape']) ? $configs['escape'] : '\\';
        // 読込文字コード
        $this->configs['fromCharset'] = isset($configs['fromCharset']) ? $configs['fromCharset'] : 'UTF-8';
        // 書込文字コード
        $this->configs['toCharset']   = isset($configs['toCharset']) ? $configs['toCharset'] : 'UTF-8';
        // SplFileObjectフラグ
        $this->configs['flags']       = isset($configs['flags']) ? $configs['flags'] : SplFileObject::READ_CSV;
    }

    public function execute() {
        ini_set('auto_detect_line_endings', true); // For mac's office excel csv
        $fromCharset = $this->configs['fromCharset'];
        $toCharset = $this->configs['toCharset'];
        if ($fromCharset != $toCharset) {
            $csv = new FilteredFile($this->filename, function($value) use($toCharset, $fromCharset){
                return mb_convert_encoding($value, $toCharset, $fromCharset);
            });
        } else {
            $csv = new FilteredFile($this->filename);
        }
        $csv->setCsvControl($this->configs['delimiter'], $this->configs['enclosure'], $this->configs['escape']);
        $csv->setFlags($this->configs['flags']);

        $originalLocale = setlocale(LC_ALL, '0'); // Backup current locale
        setlocale(LC_ALL, 'en_US.UTF-8');
        DB::transaction(function() use ($csv){
            $i = 0;
            foreach ($csv as $line ) {
                if (count($line) == 1 && empty($line[0])) {
                    continue;
                }
                $this->interceptor->import($i++, $line);
            }
            //finish
            $this->interceptor->import(null, null);
        });
        parse_str(str_replace(';', '&', $originalLocale), $locale_array);
        setlocale(LC_ALL, $locale_array); // Reset locale
    }
}
